package application.model
{
	import application.ApplicationFacade;
	import application.model.rpc.Gateway;
	import application.model.vo.Post;
	
	import flash.events.Event;
	import flash.events.NetStatusEvent;
	
	import mx.collections.ArrayCollection;
	
	import org.puremvc.interfaces.IProxy;
	import org.puremvc.patterns.proxy.Proxy;
	
	public class GatewayProxy extends Proxy implements IProxy
	{
		public static const NAME:String = "GatewayProxy";
		
		private var gateway:Gateway;
		private var firstRun:Boolean = true;
		
		public function GatewayProxy(gatewayURI:String)
		{
			super( NAME, new ArrayCollection );
			
			gateway = new Gateway(gatewayURI, "fguestbook.fguestbook");
			gateway.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
			gateway.addEventListener(Gateway.RESULT, onResult);
			gateway.addEventListener(Gateway.FAULT, onFault);
			gateway.invoke("GetPosts");
			
			sendNotification( ApplicationFacade.SERVER_REQUEST );
		}
		
		public function insertPost(post:Post):void
		{
			sendNotification(ApplicationFacade.SERVER_REQUEST);
			gateway.invoke("InsertPost", post.author, post.email, post.url, post.message);
		}
		
		public function get posts():ArrayCollection
		{
			return data as ArrayCollection;
		}
		
		private function addItem(item:Object):void
		{
			var post:Post = item as Post;
			posts.addItem( new Post(item.id, item.author, item.email, item.url, item.date, item.message) );
		}
		
		private function onNetStatus(event:NetStatusEvent):void
		{
			if ( event.info.code == "NetConnection.Call.Failed" )
			{				
				sendNotification( ApplicationFacade.SERVER_FAULT, collectErrors(event.info) );
			}
		}
		
		private function onResult(event:Event):void
		{
			sendNotification( ApplicationFacade.SERVER_RESULT );
			
			var result:Object = gateway.data;
			
			switch ( result )
			{
				case null:
					sendNotification( ApplicationFacade.MODEL_INIT );
					firstRun = false;
					break;
				
				case "inserted":
					gateway.invoke("GetPosts");
					sendNotification( ApplicationFacade.SERVER_REQUEST );
					break;
				
				default:
					if ( firstRun )
					{
						loopResult(result);
						firstRun = false;
						sendNotification( ApplicationFacade.MODEL_INIT );
					}
					else
					{
						this.data = new ArrayCollection();						
						loopResult(result);
						sendNotification( ApplicationFacade.MODEL_CHANGED );
					}
					
					break;
			}	
		}
		
		private function loopResult(result:Object):void
		{
			for ( var i:Number = 0; i < result.length; i++ )
			{
				addItem(result[i]);
			}
		}
		
		private function onFault(event:Event):void
		{
			sendNotification( ApplicationFacade.SERVER_FAULT, collectErrors(gateway.data) );
		}
		
		private function collectErrors(errorObject:Object):String
		{
			var message:String = "";
			
			for ( var p:String in errorObject )
			{
				message += p + " : " + errorObject[p] + "\n";
			}
			
			return message;
		}
	}
}